//
// Created by pzw on 24-2-26.
//

#ifndef QTTEST_ARRAYLIST_H
#define QTTEST_ARRAYLIST_H

#include <vector>
#include <iterator>
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm> // 用于std::copy

template<class T>
class Iterator;

template<class T>
class ListIterator;

/**
 * 基于C++，实现一套JAVA的ArrayList，保证JAVA方法的完全重写，使用C++的std::vector；
 * 基于vector，既能对vector进行熟悉，又能回忆JAVA的方法；
 *
 * @tparam E 模板参数
 */
template<typename E>
class ArrayList {
private:
    /* 在C++中，除非你有充足的理由，否则你的第一选择，当然应该是vector */
    std::vector<E> vector;

public:
    explicit ArrayList();
    ~ArrayList();
    bool add(E element);
    bool add(int index, E element);
    bool addAll(const std::vector<E> &source);
    bool addAll(int index, const std::vector<E> &source);
    void clear();
    ArrayList<E> clone();
    bool contains(E o);
    void ensureCapacity(size_t minCapacity);
    bool equals(const std::vector<E> &vec);
    E get(int index);
    int hashCode();
    int indexOf(const E &o);
    bool isEmpty();
    Iterator<E> iterator();
    int lastIndexOf(E o);
    ListIterator<E> listIterator();
    ListIterator<E> listIterator(int index);
    E remove(int index);
    /* 这里必须使用E &o，如果用 E o，当E = int时，这两个remove函数签名一致，会报错*/
    bool remove(E &o);
    bool removeAll(const std::vector<E> &toRemove);
    void removeIf(std::vector<E> &vec, bool (*predicate)(const E &));
    void replaceAll(E (*unaryOperator)(const E &)) = delete;
    bool retainAll(const std::vector<E> &toRetain);
    E set(int index, E element);
    int size();
    void sortWithComparator(bool (*comparator)(const E &, const E &));
    std::vector<E> subList(int fromIndex, int toIndex);;
    E *toArray();
    std::string toString();
    void trimToSize();
};

/**
 * 迭代器
 *
 * @tparam T - 模板参数
 */
template<class T>
class Iterator {
private:
    typename std::vector<T>::const_iterator begin;
    typename std::vector<T>::const_iterator current;
    typename std::vector<T>::const_iterator end;

private:
    std::vector<T> &vec;

public:
    explicit Iterator(std::vector<T> &vec)
            : begin(vec.begin()), current(vec.begin()), end(vec.end()), vec(vec) {
        /**
         * 注意，这里的初始化列表，与下列的 = 赋值，是不一样的，C++语法真他妈傻逼；
         * 构造器冒号后面的初始化列表，效率要更高；
         */
    }

    explicit Iterator(std::vector<T> &vec, size_t index)
            : begin(vec.begin()), current(vec.begin() + index), end(vec.end()) {
        /**
         * 注意，这里的初始化列表，与下列的 = 赋值，是不一样的，C++语法真他妈傻逼；
         * 构造器冒号后面的初始化列表，效率要更高；
         */
    }

    bool hasNext() {
        return current != end;
    }

    T next() {
        if (!hasNext()) {
            // Handle error or throw exception
            return T();
        }
        // 返回当前元素并移动到下一个元素
        T ret = *current;
        current++;
        return ret;
    }

    void remove() {
        if (current != vec.begin()) { // 确保不是在容器的开始位置尝试删除
            // 删除元素，并将迭代器移动到下一个有效元素
            typename std::vector<T>::iterator &itr = --current;
            current = vec.erase(itr);
        } else {
            std::cout << "Cannot remove before calling next" << std::endl;
        }
    }

    /**
     * 完整的C++原生vector itr实现，这也是我们利用C++迭代器实现java形式的迭代器的技术依据
     *
     * @return 0
     */
    int vec_itr_main() const {
        std::vector<int> ve = {-1, 0, 1, 2, 3, 4, 3, 5, 6, 7};

        for (auto it = ve.begin(); it != ve.end();) {
            if (*it == 3) {
                it = ve.erase(it); // 移除元素为3的元素，并返回下一个元素的迭代器
            } else {
                ++it;
            }
        }

        // 打印移出元素后的vector
        for (const auto &num: ve) {
            std::cout << num << " ";
        }
        std::cout << std::endl;

        return 0;
    }

};

/**
 * List迭代器
 *
 * @tparam T - 模板参数
 */
template<class T>
class ListIterator {
private:
    typename std::vector<T>::iterator begin;
    typename std::vector<T>::iterator current;
    typename std::vector<T>::iterator end;

private:
    std::vector<T> &vec;

public:
    explicit ListIterator(std::vector<T> &vec)
            : begin(vec.begin()), current(vec.begin()), end(vec.end()), vec(vec) {
        /**
         * 注意，这里的初始化列表，与下列的 = 赋值，是不一样的，C++语法真他妈傻逼；
         * 构造器冒号后面的初始化列表，效率要更高；
         */
        begin = vec.begin();
        current = vec.begin();
        end = vec.end();
        this->vec = vec;
    }

    explicit ListIterator(std::vector<T> &vec, size_t index)
            : begin(vec.begin()), current(vec.begin()), end(vec.end()), vec(vec) {
        /**
         * 注意，这里的初始化列表，与下列的 = 赋值，是不一样的，C++语法真他妈傻逼；
         * 构造器冒号后面的初始化列表，效率要更高；
         */
        begin = vec.begin();
        current = vec.begin() + index;
        end = vec.end();
        this->vec = vec;
    }

    ~ListIterator() = default;

    bool hasNext() {
        return current != end;
    }

    T next() {
        if (!hasNext()) {
            // Handle error or throw exception
            return T();
        }
        // 返回当前元素并移动到下一个元素
        T ret = *current;
        current++;
        return ret;
    }

    void remove() {
        if (current != vec.begin()) { // 确保不是在容器的开始位置尝试删除
            // 删除元素，并将迭代器移动到下一个有效元素
            typename std::vector<T>::iterator &itr = --current;
            current = vec.erase(itr);
        } else {
            std::cout << "Cannot remove before calling next" << std::endl;
        }
    }

};

int vector_api_main();

#endif //QTTEST_ARRAYLIST_H
